/*
 * =====================================================================================
 *
 *       Filename:  merge.cpp
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2015/06/09 17时44分55秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Liu Yi (), swliuyi@gmail.com
 *   Organization:  
 *
 * =====================================================================================
 */
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include  <vector>
#include  <fstream>

using namespace std;

void SplitString(const std::string& s, std::vector<std::string>& v, const std::string& c)
{
    std::string::size_type pos1, pos2;
    pos2 = s.find(c);
    pos1 = 0;
    while(std::string::npos != pos2)
    {
        v.push_back(s.substr(pos1, pos2-pos1));
        pos1 = pos2 + c.size();
        pos2 = s.find(c, pos1);
    }
    if(pos1 != s.length())
      v.push_back(s.substr(pos1));
}

class Ne
{
    public:
        string name;
        int start;
        int end;
        Ne(string n, int s, int e):name(n), start(s), end(e){}
};

bool isEndLater(const Ne & r1, const Ne & r2) 
{
    return (r1.end > r2.end);
}

bool isEndEarly(const Ne & r1, const Ne & r2) 
{
    return (r1.end < r2.end);
}

bool isStartEarly(const Ne & r1, const Ne & r2) 
{
    return (r1.start < r2.start);
}

class NeSet
{
    private:
        vector<Ne> m_neSet;
    public:
        void Add(Ne & ne)
        {
            m_neSet.push_back(ne);
        }
        vector<Ne> merge()
        {
          //  cout<<m_neSet.size()<<endl;
            vector<Ne> res;
            stable_sort(m_neSet.begin(), m_neSet.end(), isEndEarly);
       //     stable_sort(m_neSet.begin(), m_neSet.end(), isStartEarly);
//            reverse(m_neSet.begin(), m_neSet.end());
          //  for( int i = 0 ; i < m_neSet.size() ; i++ )
          //  {
          //      cout<<m_neSet[i].start<<" "<<m_neSet[i].end<<", ";
          //  }
          //  cout<<endl;

            for( size_t i = 0 ; i < m_neSet.size() ; i++ )
            {
                if( res.size() == 0 || res.back().end < m_neSet[i].start )
                {
                    res.push_back(m_neSet[i]);
                }
            }
            return res;
        }
};

int main(int argc, char *argv[])
{
    if( argc == 1 )
    {
        cout<<"./this tst ne1 ne2 ..."<<endl;
        return 1;
    }
    ifstream tst(argv[1]);
    ifstream * neArr = new ifstream[argc-2];
    for( int i = 2 ; i < argc; i++ )
    {
        neArr[i-2].open(argv[i]);
    }

    string tstline;
    while( getline(tst, tstline) )
    {
        NeSet neSet;
        string line;
        for( int i = 0 ; i < argc-2 ; i++ )//for each file
        {
            getline(neArr[i], line);//for each line
            {
                vector<string> wordList;
                SplitString(line, wordList, " ");
                for( size_t j = 0 ; j < wordList.size() ; j++ )//for each word
                {
                    int size = wordList[j].size();
                    if( wordList[j][size-1] == 'U' )
                    {
                        Ne tmp(wordList[j].substr(size-4, 2), j, j);
                        neSet.Add(tmp);
                    }
                    else if( wordList[j][size-1] == 'B' )
                    {
                        int k = j + 1;
                        while( k < size && wordList[k][wordList[k].size() - 1] != 'L')
                        {
                            k ++;
                        }
                        Ne tmp(wordList[j].substr(size-4, 2), j, k);
                        neSet.Add(tmp);
                        j = k;
                    }
                }
            }
        }
        vector<Ne> res;
        res = neSet.merge();
        vector<string> wordList;
        SplitString(tstline, wordList, " ");
        size_t j = 0;
        for( size_t i = 0 ; i < wordList.size() ; i++ )
        {
            if( j <  res.size() )
            {
                if( res[j].start == i )
                {
                    cout<<"["<<res[j].name<<" ";
                }
                cout<<wordList[i]<<" ";
                if( res[j].end == i )
                {
                    cout<<"] ";
                    j++;
                }
            }
            else
            {
                cout<<wordList[i]<<" ";
            }
        }
        cout<<endl;
    }
}
